const fp = require('lodash/fp')
// import { Container, Maybe } from './support.js'

// 一、作业一
new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello ')
  }, 10)
})
  .then(res => {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(res + 'lagou ')
      }, 10)
    })
  })
  .then(res => {
    setTimeout(() => {
      console.log(res + 'I ❤ U')
    }, 10)
  })

// 二、作业二
const cars = [
  {
    name: 'Ferrari FF',
    horsepower: 660,
    dollar_value: 700000,
    in_stock: true,
  },
  {
    name: 'Spyker C12 Zagato',
    horsepower: 650,
    dollar_value: 648000,
    in_stock: false,
  },
  {
    name: 'Jaguar XKR-S',
    horsepower: 550,
    dollar_value: 132000,
    in_stock: false,
  },
  {
    name: 'Audi R8',
    horsepower: 525,
    dollar_value: 114200,
    in_stock: false,
  },
  {
    name: 'Aston Martin One-77 ',
    horsepower: 750,
    dollar_value: 1850000,
    in_stock: true,
  },
  {
    name: 'Pagani Huayra',
    horsepower: 700,
    dollar_value: 1300000,
    in_stock: false,
  },
]
// 1. 练习1 获取最后一条数据的 in_stock
const isLastInStock = fp.flowRight(fp.prop('in_stock'), fp.last)
console.log('2-1', isLastInStock(cars))

// 2. 练习2 获取第一个 car 的 name
const isFirstName = fp.flowRight(fp.prop('name'), fp.first)
console.log('2-2', isFirstName(cars))

// 3. 练习3
let _average = function (xs) {
  return fp.reduce(fp.add, 0, xs) / xs.length
}
// let averageDollarValue = function (cars) {
//   let dollar_values = fp.map(function (car) {
//     return car.dollar_value
//   }, cars)
//   return _average(dollar_values)
// }
const averageDollarValue = cars => fp.compose(_average, () => fp.map(value => value.dollar_value, cars))()
console.log('2-3', averageDollarValue(cars))

// 4. 练习4 sanitizeNames(["Hello World"]) => ["hello_world"]
let _underscore = fp.replace(/\W+/g, '_') // < - - 无须改动，并在 sanitizeNames中使用它
const sanitizeNames = array => fp.map(fp.flowRight(_underscore, fp.toLower), array)
console.log('2-4', sanitizeNames(['Hello World']))

// 三、作业三
class Container {
  static of(value) {
    return new Container(value)
  }

  constructor(value) {
    this._value = value
  }

  map(fn) {
    return Container.of(fn(this._value))
  }
}
class Maybe {
  static of(value) {
    return new Maybe(value)
  }

  constructor(value) {
    this._value = value
  }

  isNothing() {
    return this._value === null || this._value === undefined
  }

  map(fn) {
    return this.isNothing() ? this : Maybe.of(fn(this._value))
  }
}

// 1. 练习1
let maybe = Maybe.of([5, 6, 1])
let ex1 = num => maybe.map(arr => fp.map(v => fp.add(v, num), arr))
console.log('3-1 ex1', ex1(2))

// 2. 练习2
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do'])
let ex2 = xs => xs.map(value => fp.first(value))
console.log('3-2 ex2', ex2(xs))

// 3. 练习3
let safeProp = fp.curry(function (x, o) {
  return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }
let safePropCurry = safeProp('name')
let ex3 = user => safeProp('name')(user).map(str => fp.first(str))
console.log('3-3 ex3', ex3(user))

// 4. 练习4
let ex4 = n => Maybe.of(n).map(n => parseInt(n))
console.log('3-4 ex4', ex4(null))
